package com.dhu.stylefit.service;

import com.dhu.stylefit.converter.UsersConverter;
import com.dhu.stylefit.dao.Users;
import com.dhu.stylefit.dao.UsersRepository;
import com.dhu.stylefit.dto.UsersDTO;
import com.dhu.stylefit.security.JwtTokenProvider;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.Optional;

@Slf4j
@Service
public class UsersServiceImpl implements UsersService {

    @Autowired
    private UsersRepository usersRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Override
    public UsersDTO getUsersById(long id) {
        try {
            Optional<Users> usersOptional = usersRepository.findById(id);
            if (usersOptional.isPresent()) {
                Users users = usersOptional.get();
                UsersDTO usersDTO = new UsersDTO();
                usersDTO.setUser_id(users.getId());
                usersDTO.setUsername(users.getUsername());
                usersDTO.setEmail(users.getEmail());
                usersDTO.setPasswordHash(users.getPasswordHash());
                return usersDTO;
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Failed to get user by ID: " + e.getMessage());
        }
    }

    @Override
    public Long addNewUsers(UsersDTO usersDTO) {
        try {
            Users users = new Users();
            users.setUsername(usersDTO.getUsername());
            users.setEmail(usersDTO.getEmail());
            users.setPasswordHash(passwordEncoder.encode(usersDTO.getPasswordHash()));
            Users savedUsers = usersRepository.save(users);
            return savedUsers.getId();
        } catch (Exception e) {
            throw new RuntimeException("Failed to add new user: " + e.getMessage());
        }
    }

    @Override
    public void deleteUsersById(long id) {
        try {
            if (!usersRepository.existsById(id)) {
                throw new RuntimeException("User not found with ID: " + id);
            }
            usersRepository.deleteById(id);
        } catch (Exception e) {
            throw new RuntimeException("Failed to delete user: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public UsersDTO updateUsersById(UsersDTO usersDTO) {
        try {
            Optional<Users> usersOptional = usersRepository.findById(usersDTO.getUser_id());
            if (usersOptional.isPresent()) {
                Users users = usersOptional.get();
                users.setUsername(usersDTO.getUsername());
                users.setEmail(usersDTO.getEmail());
                users.setPasswordHash(passwordEncoder.encode(usersDTO.getPasswordHash()));
                Users updatedUsers = usersRepository.save(users);
                UsersDTO updatedUsersDTO = new UsersDTO();
                updatedUsersDTO.setUser_id(updatedUsers.getId());
                updatedUsersDTO.setUsername(updatedUsers.getUsername());
                updatedUsersDTO.setEmail(updatedUsers.getEmail());
                updatedUsersDTO.setPasswordHash(updatedUsers.getPasswordHash());
                return updatedUsersDTO;
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Failed to update user: " + e.getMessage());
        }
    }

    @Override
    public UsersDTO getUsersByEmail(String email) {
        try {
            List<Users> usersList = usersRepository.findByEmail(email);
            if (!CollectionUtils.isEmpty(usersList)) {
                Users users = usersList.get(0);
                UsersDTO usersDTO = new UsersDTO();
                usersDTO.setUser_id(users.getId());
                usersDTO.setUsername(users.getUsername());
                usersDTO.setEmail(users.getEmail());
                usersDTO.setPasswordHash(users.getPasswordHash());
                return usersDTO;
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Failed to get user by email: " + e.getMessage());
        }
    }

    @Override
    public String loginUser(UsersDTO usersDTO) {
        try {
            List<Users> usersList = usersRepository.findByEmail(usersDTO.getEmail());
            if (!CollectionUtils.isEmpty(usersList)) {
                Users user = usersList.get(0);
                if (passwordEncoder.matches(usersDTO.getPasswordHash(), user.getPasswordHash())) {
                    return jwtTokenProvider.createToken(user.getId(), user.getEmail());
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Failed to login user: " + e.getMessage());
        }
    }

    @Override
    public String registerUser(UsersDTO usersDTO) {
        try {
            // 检查邮箱是否已存在
            List<Users> existingUsers = usersRepository.findByEmail(usersDTO.getEmail());
            if (!CollectionUtils.isEmpty(existingUsers)) {
                throw new IllegalArgumentException("Email already exists");
            }

            // 创建新用户
            Users user = new Users();
            user.setUsername(usersDTO.getUsername());
            user.setEmail(usersDTO.getEmail());
            user.setPasswordHash(passwordEncoder.encode(usersDTO.getPasswordHash()));

            // 保存用户
            Users savedUser = usersRepository.save(user);

            // 生成token
            return jwtTokenProvider.createToken(savedUser.getId(), savedUser.getEmail());
        } catch (Exception e) {
            throw new RuntimeException("Failed to register user: " + e.getMessage());
        }
    }

}
